/*
 * Copyright 2010 Assert Developments
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package be.ad.coffeebreak.services;

import be.ad.coffeebreak.domain.Project;
import org.apache.log4j.Logger;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import java.util.LinkedList;
import java.util.List;

/**
 * A bean implementation of project services.
 *
 * @author Stefan Bangels
 */
@Stateless
@SuppressWarnings("unused")
public class ProjectsServiceBean implements ProjectsService {

    private final Logger auditLogger = Logger.getLogger("audit");
    private final Logger logger = Logger.getLogger(getClass());

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    public Project findProjectById(long projectId) {
        return entityManager.find(Project.class, projectId);
    }

    @Override
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    public List<Project> findProjectsByUserId(long userId) {
        try {
            TypedQuery<Project> query = entityManager.createNamedQuery(Project.QUERY_FIND_PROJECTS_BY_USER_ID, Project.class);
            query.setParameter(Project.QUERY_PARAM_USER_ID, userId);
            return query.getResultList();
        } catch (NoResultException e) {
            return new LinkedList<Project>();
        }
    }

    @Override
    public Project saveProject(Project project) {
        return project.getId() == null ? insertProject(project) : updateProject(project);
    }

    /**
     * Create a project.
     *
     * @param project the project
     * @return the created project
     */
    private Project insertProject(Project project) {
        auditLogger.info("creating project: " + project);
        entityManager.persist(project);
        return project;
    }

    /**
     * Update a project.
     *
     * @param project the project
     * @return the updated project
     */
    private Project updateProject(Project project) {
        auditLogger.info("updating project: " + project);
        entityManager.merge(project);
        return project;
    }

    @Override
    public void deleteProject(long projectId) {
        auditLogger.info("deleting project with projectId=" + projectId);
        Project project = findProjectById(projectId);
        if (project == null) {
            logger.warn("cannot delete project, project not found! (id=" + projectId + ")");
            return;
        }
        entityManager.remove(project);
    }

}
